
// 节流 高频事件触发，但在n秒内只会执行一次，所以节流会稀释函数的执行频率
export function throttle(this: any,limit = 500): any {
    let flag = true
    return (target: any, key: string, descriptor: any) => {
        const func = descriptor.value
        descriptor.value = async (...args: any[]) => {
            if(!flag) return
            flag = false
            try {
                func.apply(this, ...args)
            } catch (error) {
                console.log(error)
            }
            if (!limit) return flag = true
            setTimeout(() => {
                flag = true
            }, limit);
        }
    }
}
// 防抖 触发高频事件后n秒内函数只会执行一次，如果n秒内高频事件再次被触发，则重新计算时间
export function debounce(this: any,limit = 500): any {
    let flag: any;
    return (target: any, key: string, descriptor: any) => {
       
        const func = descriptor.value
        descriptor.value = async (...args: any[]) => {
           
            clearTimeout(flag);
            flag = setTimeout(() => {
                func.apply(this, args);
            }, limit);

            
        }
    }
}
//需要支持方法计时，异常捕获
export function catchError(this: any,msg: string) {
  return  (target: any, key: string, descriptor: PropertyDescriptor) =>{
   
    const fn = descriptor.value;
    descriptor.value =  async (...args: any[])=> {
        const timestamp1=new Date().getTime();
        try {
            // TODO：调用前自定义逻辑
            //实际方法调用
            const re = await fn.apply(this, args);

            // TODO：调用后自定义逻辑
            
            const timestamp2=new Date().getTime();
            const diff = timestamp2-timestamp1;
            console.log(`获取结果花费${diff}毫秒，结果为==>`,re);
        
        } catch (error) {
            console.log(msg,"error :===>"+error);
        }finally {
            // const timestamp2=new Date().getTime();
            // const diff = timestamp2-timestamp1
            // console.log(`函数执行花费：=>>>>>${diff}毫秒`);
        }
    };
  }
}

/**
@example @limitFrequency('debounce') @limitFrequency('throttle')
@params type:String enum('debounce'，'throttle')
@params wait:Number 延迟时间默认500毫秒，也可自定义传入
@note 支持箭头函数的写法了，且将截流throttle函数和防抖debounce函数合二为一
防抖 debounce: 任务被调用后, 在一定延迟后才执行, 若再次被调用, 则重新计算延迟时间
截流 throttle: 一定时间内, 任务不管被调用多少次, 只实际执行一次
*/
export function limitFrequency(this: any,type: string, wait = 500) {
    return  (pageInstance: any, funcName: any, descriptor: { value: (...args: any[]) => void; initializer: { (): any; (): (...args: any[]) => void } })=> {
        let timer: any;
        const cacheValue = descriptor?.value || descriptor?.initializer()
        const callBack = (...args: any[]) => {
            if (type == 'debounce') {
                if (timer) {
                    clearTimeout(timer);
                    timer = null;
                }
                timer = setTimeout(() => {
                    cacheValue.apply(this, args)
                    clearTimeout(timer);
                    timer = null; 
                }, wait)
            }
            if (type == 'throttle' && !timer) {
                timer = setTimeout(() => {
                    cacheValue.apply(this, args)
                    clearTimeout(timer);
                    timer = null;
                }, wait)
            }
        };
        if (cacheValue.name == funcName) {
            descriptor.value = callBack
        } else {
            descriptor.initializer = () => callBack;
        }
        return descriptor;
    }
}

